昨天講到的widget的實例化成為element的過程,官方稱這個過程為widget was inflated into element
abstract class Element extends DiagnosticableTree implements BuildContext {
...
Element inflateWidget(Widget newWidget, Object? newSlot) {
...
final Element newChild = newWidget.createElement();
...
newChild.mount(this, newSlot);
...
return newChild;
}
...
}
從element的source code可以看到有一個inflateWidget它會傳入newWidget參,呼叫newWidget的createElement並且assign到一個叫newChild的變數,看到這裡我們也可以明白element為何會稱作widget的實例化了,不過還沒完可以看到下面幾行會去呼叫newChild的mount並且把this也就是element自己傳到mount method裡面,我們接下來看mount又做了什麼
/// Add this element to the tree in the given slot of the given parent.
///
/// The framework calls this function when a newly created element is added to
/// the tree for the first time. Use this method to initialize state that
/// depends on having a parent. State that is independent of the parent can
/// more easily be initialized in the constructor.
///
/// This method transitions the element from the "initial" lifecycle state to
/// the "active" lifecycle state.
///
/// Subclasses that override this method are likely to want to also override
/// [update], [visitChildren], [RenderObjectElement.insertRenderObjectChild],
/// [RenderObjectElement.moveRenderObjectChild], and
/// [RenderObjectElement.removeRenderObjectChild].
///
/// Implementations of this method should start with a call to the inherited
/// method, as in `super.mount(parent, newSlot)`.
@mustCallSuper
void mount(Element? parent, Object? newSlot) {
{
...
_parent = parent;
...
_depth = _parent != null ? _parent!.depth + 1 : 1;
...
}
我們先看第一行註解
Add this element to the tree in the given slot of the given parent.
白話來講就是把element放在另一個element底下串成一棵樹。
再看mount method的第一個參數被命名為parent,跟前面一段source code連成一起看就變成這樣
abstract class Element extends DiagnosticableTree implements BuildContext {
...
Element inflateWidget(Widget newWidget, Object? newSlot) {
final Element newChild = newWidget.createElement();
...
newChild.mount(this, newSlot);
...
}
...
void mount(Element? parent, Object? newSlot) {
{
...
_parent = parent;
...
_depth = _parent != null ? _parent!.depth + 1 : 1;
...
}
}
widget轉化成child element,再被mout到parent element上。
恩….看到這裡總算是你感受到一點樹的感覺了,可以想像flutter應該是透過一次次把widget infalted elemnt並mout起來串成一棵樹了,但總覺好像還是少了一點什麼….
其實上面講的是widget tree轉變成element tree的過程,但是只介紹了上下層(parent <-> child)的轉變而已。
明天會用一個widget tree當做範例深入解釋一顆完整的widget tree怎麼透過visit轉換成element tree